#pragma once



#include <opencv2/opencv.hpp> 
using namespace cv;

using namespace std;
//#include <vector>  


/// <summary>
/// 线图
/// </summary>
void showHistogram_demo(Mat& image)
{
	//图像三通道分离
	vector<Mat> bgr_plane;
	split(image, bgr_plane);
	//定义参数变量
	const int channels[1] = { 0 };
	const int bins[1] = { 256 };
	float hranges[2] = { 0,255 };
	const float* ranges[1] = { hranges };

	Mat b_hist;
	Mat g_hist;
	Mat r_hist;

	//计算blue green red 通道的直方图   支持多张图   不用mask  bins灰度级别  ranges控制值的范围
	calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);
	calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges);
	calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges);
	//显示直方图
	int hist_w = 512;
	int hist_h = 400;
	int bin_w = cvRound((double)hist_w / bins[0]);
	//创建画布
	Mat histInmage = Mat::zeros(hist_h, hist_w, CV_8UC3);
	//归一化直方图数据 让值不超出画布
	normalize(b_hist, b_hist, 0, histInmage.rows, NORM_MINMAX, -1, Mat());
	normalize(g_hist, g_hist, 0, histInmage.rows, NORM_MINMAX, -1, Mat());
	normalize(r_hist, r_hist, 0, histInmage.rows, NORM_MINMAX, -1, Mat());
	//绘制直方图
	for (int i = 1; i < bins[0]; i++)
	{
		//每个像素值获得一条线
		line(histInmage,
			Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))),
			Scalar(255, 0, 0), 2, 8, 0);
		line(histInmage,
			Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))),
			Scalar(0, 255, 0), 2, 8, 0);
		line(histInmage,
			Point(bin_w * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
			Point(bin_w * (i), hist_h - cvRound(b_hist.at<float>(i))),
			Scalar(0, 0, 255), 2, 8, 0);
	}
	namedWindow("histogram_demo", WINDOW_AUTOSIZE);
	imshow("histogram_demo", histInmage);
	imshow("sourcePic", image);
}

/// <summary>
/// 二维直方图
/// </summary>
/// <param name="image"></param>
void histogram_2d_demo(Mat& image)
{
	Mat hsv, hs_hist;
	//转到hsv
	cvtColor(image, hsv, COLOR_BGR2HSV);
	int hbins = 180;
	int sbins = 256;
	int hist_bins[] = { hbins,sbins };
	float h_range[] = { 0,180 };
	float s_range[] = { 0,256 };
	const float* hs_ranges[] = { h_range,s_range };
	int hs_channels[] = { 0,1 };
	calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);

	double maxVal = 0;
	minMaxLoc(hs_hist, 0, &maxVal, 0, 0);
	int scale = 2;
	Mat hist2d_image = Mat::zeros(sbins * scale, hbins * scale, CV_8UC3);

	for (int h = 0; h < hbins; h++)
	{
		for (int s = 0; s < sbins; s++)
		{
			float binVal = hs_hist.at<float>(h, s);
			int intensity = cvRound(binVal * 255 / maxVal);
			rectangle(hist2d_image,
				Point(h * scale, s * scale),
				Point((h + 1) * scale - 1, (s + 1) * scale - 1),
				Scalar::all(intensity),
				-1);
		}
	}
	applyColorMap(hist2d_image, hist2d_image, COLORMAP_JET);
	imshow("HS", hist2d_image);

}

/// <summary>
/// 灰度图像直方图均衡化
/// </summary>
/// <param name="image"></param>
void histogram_eq_demo(Mat& image)
{
	//原图
	imshow("source", image);
	//变为单通道灰度图
	Mat gray;
	cvtColor(image, gray, COLOR_BGR2GRAY);
	imshow("gray", gray);
	//均衡开始
	Mat dst;
	equalizeHist(gray, dst);
	imshow("eq", dst);
}

/// <summary>
/// 彩色图像的直方图均衡HSV
/// </summary>
/// <param name="image"></param>
void histogram_eqc_demo(Mat& image)
{
	imshow("source", image);

	Mat hsv;
	cvtColor(image, hsv, COLOR_BGR2HSV);
	vector<Mat> hsv_channels;
	split(hsv, hsv_channels);
	Mat V = hsv_channels.at(2);
	Mat S = hsv_channels.at(1);
	Mat H = hsv_channels.at(0);

	//equalizeHist(H, hsv_channels.at(0));
	//equalizeHist(S, hsv_channels.at(1));
	equalizeHist(V, hsv_channels.at(2));
	merge(hsv_channels, hsv);

	Mat dst;
	cvtColor(hsv, dst, COLOR_HSV2BGR);
	imshow("eq", dst);
}
